Skip to content

net: fix SocketAddress.parse default port handling#62912

Open
araujogui wants to merge 5 commits intonodejs:mainfrom
araujogui:fix-socketaddress-port
Open

net: fix SocketAddress.parse default port handling#62912
araujogui wants to merge 5 commits intonodejs:mainfrom
araujogui:fix-socketaddress-port

Conversation

@araujogui
Copy link
Copy Markdown
Member

Fixes #62906

Copilot AI review requested due to automatic review settings April 23, 2026 14:47
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem. labels Apr 23, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes net.SocketAddress.parse() so it correctly preserves explicit default ports (notably :80) that are otherwise dropped by URL.parse() when using an http:// base, aligning behavior with expectations and documentation.

Changes:

  • Update SocketAddress.parse() to derive the port from the raw input string rather than url.port.
  • Simplify the parse return path to a single SocketAddress construction for both IPv4 and IPv6.
  • Add regression tests covering IPv4/IPv6 with explicit ports 80 and 443.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
lib/internal/socketaddress.js Fixes default-port handling by parsing the port from the raw input instead of URLParse(...).port.
test/parallel/test-socketaddress.js Adds regression coverage ensuring explicit :80/:443 are preserved for both IPv4 and IPv6.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

❌ Patch coverage is 94.73684% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 89.63%. Comparing base (66054cc) to head (5c4f673).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/socketaddress.js 94.73% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62912      +/-   ##
==========================================
- Coverage   91.48%   89.63%   -1.86%     
==========================================
  Files         358      708     +350     
  Lines      151591   220421   +68830     
  Branches    23925    42278   +18353     
==========================================
+ Hits       138690   197578   +58888     
- Misses      12625    14705    +2080     
- Partials      276     8138    +7862     
Files with missing lines Coverage Δ
lib/internal/socketaddress.js 98.53% <94.73%> (-0.45%) ⬇️

... and 473 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread lib/internal/socketaddress.js Outdated
@araujogui araujogui force-pushed the fix-socketaddress-port branch from b274a64 to 87d545a Compare April 30, 2026 16:08
@araujogui araujogui force-pushed the fix-socketaddress-port branch from 87d545a to 7563aff Compare April 30, 2026 16:13
@araujogui araujogui requested a review from aduh95 April 30, 2026 16:15
@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Apr 30, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 30, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@cookesan
Copy link
Copy Markdown
Contributor

cookesan commented Apr 30, 2026

I noticed one extra behavior change from parsing the port with lastIndexOf(':') and parseInt(): it can pick up a colon that belongs to userinfo rather than the host port.

For example, current main keeps these at port 0 because there is no host port:

SocketAddress.parse('user:[email protected]')
SocketAddress.parse('user:[email protected]')

With this patch they become ports 80 and 81 respectively. That may be acceptable if userinfo-shaped inputs are considered out of scope, but it is a behavior change beyond preserving explicit default host ports.

An alternative is to keep using the HTTP URL parse for the address and existing non-default ports, and only when url.port is empty ask a scheme with no default port for the port value. For example:

URLParse(`socket://${input}`).port

That preserves the existing URL host parsing while recovering explicit host ports like :80.

@araujogui
Copy link
Copy Markdown
Member Author

I noticed one extra behavior change from parsing the port with lastIndexOf(':') and parseInt(): it can pick up a colon that belongs to userinfo rather than the host port.

For example, current main keeps these at port 0 because there is no host port:

SocketAddress.parse('user:[email protected]')
SocketAddress.parse('user:[email protected]')

With this patch they become ports 80 and 81 respectively. That may be acceptable if userinfo-shaped inputs are considered out of scope, but it is a behavior change beyond preserving explicit default host ports.

An alternative is to keep using the HTTP URL parse for the address and existing non-default ports, and only when url.port is empty ask a scheme with no default port for the port value. For example:

URLParse(`socket://${input}`).port

That preserves the existing URL host parsing while recovering explicit host ports like :80.

Great finding and solution, thank you @cookesan

@araujogui
Copy link
Copy Markdown
Member Author

I noticed one extra behavior change from parsing the port with lastIndexOf(':') and parseInt(): it can pick up a colon that belongs to userinfo rather than the host port.
For example, current main keeps these at port 0 because there is no host port:

SocketAddress.parse('user:[email protected]')
SocketAddress.parse('user:[email protected]')

With this patch they become ports 80 and 81 respectively. That may be acceptable if userinfo-shaped inputs are considered out of scope, but it is a behavior change beyond preserving explicit default host ports.
An alternative is to keep using the HTTP URL parse for the address and existing non-default ports, and only when url.port is empty ask a scheme with no default port for the port value. For example:

URLParse(`socket://${input}`).port

That preserves the existing URL host parsing while recovering explicit host ports like :80.

Great finding and solution, thank you @cookesan

Actually, I did some benchmarks and noticed the double URL.parse solution is definitely simpler but ~25% slower than a string-based approach. So I pushed the string solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SocketAddress parses port 80 as 0

6 participants